package vcp.server.requesthandler;

import ocsf.server.ConnectionToClient;
import vcp.client.request.UserLoginRequest;
import vcp.client.request.response.ResponseRequest;
import vcp.client.utility.Common.UserNotification;
import vcp.entity.Customer;
import vcp.entity.Site;
import vcp.entity.User;
import vcp.entity.Worker;
import vcp.enums.SubscriptionType;
import vcp.enums.UserType;
import vcp.server.interfaces.IServer;
/**
 * 
 * @author VCP team
 *<p> class handles request from client related to user login </p>
 */
public class UserLoginRequestHandler extends RequestHandler <UserLoginRequest>
{
	/**
	 * class constructor
	 * @param server
	 */
	public UserLoginRequestHandler ( IServer server )
	{
		super(server);
	}

	@Override
	public void execute ( UserLoginRequest request, ConnectionToClient client )
	{
		ResponseRequest response = new ResponseRequest(request.getRequestID(), null);

		User user = this.getDaoFactory().getUserDAO().findByID(request.getID());

		String error = this.userVerificaton(request, user);
		if ( error != null )
		{
			System.out.println("User not found will show error on client");
			response.setErrorMessage(error);
		}
		else
		{
			if ( user.getUserType() == UserType.CUSTOMER )
			{
				Customer customer = this.getDaoFactory().getCustomerDAO().findByEntity(user);

				if ( this.isSubscriberedCustomer(customer) )
				{
					response.setData(customer);
				}
				else
				{
					response.setErrorMessage(UserNotification.USER_DOESNT_EXIST);
				}
			}
			else
			{
				Worker worker = this.getDaoFactory().getWorkerDAO().findByEntity(user);
				for ( Site site : worker.getSites() )
				{
					this.getDaoFactory().getSiteDAO().getSiteLotsOnDemand(site);
				}

				response.setData(worker);
			}
		}

		if ( response.isSucceded() )
		{
			client.setInfo(User.class.toString(), user.getUserID());
			this.getDaoFactory().getUserDAO().updatedLoggedInStatus(user.getUserID(), true);
		}
		this.sendResponse(response, client);
	}
	/**
	 *  verify user login
	 * @param request
	 * @param user
	 * @return null if login success
	 */
	private String userVerificaton ( UserLoginRequest request, User user )
	{
		String error = null;
		if ( user == null )
		{
			error = UserNotification.USER_DOESNT_EXIST;
		}
		else if ( ! user.getPassword().equalsIgnoreCase(request.getPassword()) )
		{
			error = UserNotification.INCORRECT_PASSWORD;
		}
		else if ( this.isUserLoggedIn(request.getID()) )
		{
			error = String.format(UserNotification.USER__ID__ALREADY_LOGGED_IN, request.getID());
		}
		return error;
	}
	/**
	 * check if customer is subscribed
	 * @param customer
	 * @return true if subscribed
	 */
	private boolean isSubscriberedCustomer ( Customer customer )
	{
		return customer.getSubscriptions().get(0).getSubscriptionType() != SubscriptionType.ONE_TIME_USE;
	}
	/**
	 * check if user is logged in
	 * @param userID
	 * @return true if user is logged in
	 */
	private boolean isUserLoggedIn ( int userID )
	{
		boolean isUserLoggedIn = false;

		for ( ConnectionToClient connection : this.server.getConnections() )
		{
			Integer connectedUserID = (Integer) connection.getInfo(User.class.toString());
			if ( connectedUserID != null )
			{
				isUserLoggedIn = connectedUserID == userID;
				if ( isUserLoggedIn )
				{
					break;
				}
			}
		}

		return isUserLoggedIn;
	}

}
